grammar V3;
//@header{
//package com.bls.executor.parser;
//}
// 8秒之后， 梁子豪 在 2019级梁子豪个人工作区 帮区执行消息板工具,消息板为 2019级梁子豪论文消息板 ，消息内容为 XX 。
// 当在 2019级梁子豪个人工作区 帮区监听到 设备故障 消息的类型，则 梁子豪 在 2019级梁子豪个人工作区 帮区执行消息板工具,消息板为 2019级梁子豪论文消息板 ，消息内容为 XX 。
script: (stmt)+;
stmt: simpleStmt | complexStmt ;
// 简单句 (2类):工具运行的原子句（即时型、监听型、定时型）
simpleStmt: intenseStmt | listenStmt | scheduleStmt ;

// 1.即时型 如： 张三 在 喇叭 帮区执行 喇叭 工具的 发声 部件， 参数1 为 值1 ，返回结果为 A 。
intenseStmt: authoriseStmt | runToolStmt | setStmt; // 后续扩展帮区帮区元素的管理
runToolStmt: (Identifier place Run Identifier Tool_s Identifier Unit (Comma|(Comma paramStmt)+ Comma) Return Identifier )Dot? | notifyStmt;
notifyStmt: Identifier place Run ChatTool Comma ChatRoom Is Identifier (Comma Reciver Is Identifier)? Comma MsgContent Is Identifier Dot?;
// 定义工具部件参数
paramStmt: Identifier Is Identifier ;
place: At Identifier Band;

// 2.监听型
//监听型语句，如：当 在xx帮区 监听到 设备故障 消息的类型，则 张三 在 xx帮区 执行 消息板工具 ，消息板为XXX，消息内容为XXX。
listenStmt: When place Listen Identifier Type_sMessage Comma Then intenseStmt;


// 3.定时型
// (1) 周期
// 如：每1天8点，张三 在 喇叭 帮区 执行 喇叭 工具的 发声 部件，喇叭id为xx。
// (2) 延时
// 如：2小时 之后，张三 在 喇叭 帮区 执行 喇叭 工具的 发声 部件，喇叭id为xx。
scheduleStmt: timeAdverbial Comma (intenseStmt | listenStmt);
timeAdverbial: period | delay;
period: Every (Year?|Number Year)(Month?|Number Month)(Day?|Number Day)(Hour?|Number Hour)(Minute?|Number Minute)(Second?|Number Second);
delay: (Year?|Number Year)(Month?|Number Month)(Day?|Number Day)(Hour?|Number Hour)(Minute?|Number Minute)(Second?|Number Second) After;

// 复杂句 (2类): 条件句 + 循环句
complexStmt: (ifStmt | loopStmt)+;

// 1.条件句
ifStmt: If conditionStmt Comma Then simpleStmt;
conditionStmt: (Identifier Operate Identifier);

// 2.循环句
loopStmt: Repeat simpleStmt Identifier Times;

// 设置变量
setStmt: Set (Comma? Identifier Is value)+ Dot?;
value: (complexStmt | simpleStmt | Identifier);

// 授权语句
authoriseStmt: (timeFrame Comma)? (Allow|Ban) Identifier place Run Identifier (Tool|Tool_s Identifier Unit) Dot?;
// 时段
timeFrame: (Number Month To Number Month)?
            (Number Day To Day Month)?
            (Week Number To Week Number)?
            ( Number Hour To Number Hour)?
            ( Number Minute To Number Minute)?
            ( Number Second To Number Second)? ;

At: '在';
Band: '帮区';
Run: '执行' | '调用';
Tool_s: '工具的';
Unit: '部件';
Is: '为';
Return: '返回结果为';

Tool:'工具';
When: '当';
Listen: '监听到';
MessageBus: '消息总线';
Type_sMessage: '消息的类型';
Then: '则';
ChatTool: '消息板工具';
ChatRoom: '消息板';
MsgContent: '消息内容';
Reciver: '接收者';

After: '之后' | '后';
Every: '每';
Year: '年';
Month: '月';
Day: '日'|'天';
Hour: '时'|'点';
Minute: '分'|'分钟';
Second: '秒';

If: '如果';
Operate: '大于' | '等于' | '小于' | '存在于' | '包含';

Repeat: '重复';
Times: '次';

Set: '设置';

To:'至';
Allow: '允许';
Ban:'禁止';
Week:'星期';

Comma: ',' | '，';
Dot :'.'|'。';
Number :[0-9]+;
Identifier: ('"' | '”' | ' ') ([a-zA-Z0-9$_] | [\u4E00-\u9FA5])+ ('"' | '”' | ' ');

Ws :[\r\n]+ -> skip;
Comment :'//' ~[\r\n]* -> channel(HIDDEN);